package net.alteiar.ui.algorithms;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.event.EventListenerList;

import net.alteiar.images.BasicImage;
import net.alteiar.images.IDrawable;
import net.alteiar.thread.Task;
import net.alteiar.thread.WorkerPool;

public abstract class PanelAlgorithmsDetails<E extends Algorithm> extends JPanel {
	private static final long serialVersionUID = 1L;

	private final E algo;

	private IDrawable resultImage;

	public PanelAlgorithmsDetails(E algo) {
		this.algo = algo;
	}

	protected E getAlgorithm() {
		return algo;
	}

	protected abstract void updateParams();

	public void execute(final BasicImage img) {
		Task t = new Task() {
			@Override
			public void run() {
				updateParams();
				resultImage = algo.execute(img);
				fireActionPerformed();
			}
		};
		WorkerPool.INSTANCE.addTask(t);
	}

	public IDrawable getImage() {
		return resultImage;
	}

	protected void fireActionPerformed() {
		ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
				"");
		fireActionPerformed(event);
	}

	/**
	 * Notifies all listeners that have registered interest for notification on
	 * this event type. The event instance is lazily created using the
	 * <code>event</code> parameter.
	 * 
	 * @param event
	 *            the <code>ActionEvent</code> object
	 * @see EventListenerList
	 */
	protected void fireActionPerformed(ActionEvent event) {
		// Guaranteed to return a non-null array
		Object[] listeners = listenerList.getListenerList();
		ActionEvent e = null;
		// Process the listeners last to first, notifying
		// those that are interested in this event
		for (int i = listeners.length - 2; i >= 0; i -= 2) {
			if (listeners[i] == ActionListener.class) {
				// Lazily create the event:
				if (e == null) {
					String actionCommand = event.getActionCommand();
					e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
							actionCommand, event.getWhen(),
							event.getModifiers());
				}
				((ActionListener) listeners[i + 1]).actionPerformed(e);
			}
		}
	}

	public void addActionListener(ActionListener l) {
		listenerList.add(ActionListener.class, l);
	}

	@Override
	public String toString() {
		return algo.toString();
	}
}
